﻿using MyMusicPlay._4._0.Manager;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyMusicPlay._4._0
{
    public static class TimeFactory
    {
        public static readonly TimerManager manager = PlayApplication.GetManager<TimerManager>();

        public static void Add(int millisecond, TimerAction action)
        {
            if (millisecond == 0)
            {
                return;
            }
            var timeData = manager.GetTimerData(millisecond);
            timeData.InsertAction(action);
        }

        public static void Remove(int millisecond, int index)
        {
            manager.RemoveTimerData(millisecond, index);
        }
    }

    public class TimeData
    {
        #region 阻塞
        /// <summary>
        /// 禁止进入次数
        /// </summary>
        private int _forbidEnterCount = 0;
        /// <summary>
        /// 是否允许进入
        /// </summary>
        private bool _allowEnter = true;
        /// <summary>
        /// 当前执行的函数
        /// </summary>
        private TimerAction _curAction;
        #endregion

        private int _executeCount;
        private int _millisecond;
        private Timer timer;
        private ConcurrentDictionary<int, TimerAction> _keyValues = new();
        public TimeData(int millisecond)
        {
            _millisecond = millisecond;
            timer = CreateTimer();
        }

        public void InsertAction(TimerAction action)
        {
            _keyValues.TryAdd(action.ID, action);
        }

        public void DeleteAction(int index)
        {
            TimerAction action = null;
            _keyValues.TryRemove(index, out action);
        }

        private Timer CreateTimer()
        {
            var time = new Timer(Check, null, 0, _millisecond);
            return time;
        }

        private void Check(object obj)
        {
            if (!_allowEnter)
            {
                _forbidEnterCount++;
                if (_forbidEnterCount >= 10)
                {
                    if (_curAction != null)
                    {
                        Log.Write($"Timer被阻塞,Function.Name:[{_curAction.FunctionName}]");
                    }
                    else
                    {
                        Log.Write($"Timer被阻塞,似乎是从开始就被阻塞了");
                    }

                    //删除阻塞函数
                    DeleteAction(_curAction.ID);
                    Log.Write($"删除阻塞函数[{_curAction.FunctionName}]");
                    _forbidEnterCount = 0;
                }
            }

            lock (this)
            {
                if (!TimerManager.totalSwitch)
                {
                    return;
                }
                try
                {
                    _allowEnter = false;
                    List<TimerAction> list = new List<TimerAction>(_keyValues.Values);
                    foreach (var item in list)
                    {
                        try
                        {
                            _curAction = item;
                            item.action();
                        }
                        catch (Exception ex)
                        {
                            Log.Write($"function:[{_curAction!.FunctionName}]发生报错");
                        }
                    }

                    _forbidEnterCount = 0;
                }
                catch (Exception ex)
                {
                    Log.Write(ex.Message);
                }
                finally
                {
                    _allowEnter = true;
                    Interlocked.Increment(ref _executeCount);
                }
            }
        }
    }

}
